package com.zhouwr.protocol;

import com.zhouwr.common.message.ReceiveMessage;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufUtil;
import io.netty.channel.ChannelHandler.Sharable;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToMessageDecoder;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.binary.Hex;
import org.jeecg.utils.CRCUtil;
import org.jeecg.utils.HexConvertUtil;

import java.util.List;

/**
 * @program: forallcn-iotps
 * @description: 解码器
 * @author: zhouwr
 * @create: 2020-12-08 16:22
 * @version：1.0
 **/
@Slf4j
@Sharable
public class Wireless120Decoder extends MessageToMessageDecoder<ByteBuf> {
    @Override
    protected void decode(ChannelHandlerContext ctx, ByteBuf msg, List<Object> out) throws Exception {
        byte[] bytes = ByteBufUtil.getBytes(msg);
        log.info("Wireless120Decoder.decode >>>>>> {}", Hex.encodeHexString(bytes));

        /* 心跳，抛给后台自己处理 */
        if ("heart".equals(new String(bytes))) {
            log.info("心跳");
        } else {
            /* 数据 */
            int len = bytes.length;
            // CRC校验

            /* 报文后两位CRC校验值 */
            byte[] c = {bytes[len - 2], bytes[len - 1]};
            String srcCRC = HexConvertUtil.BinaryToHexString(c);
            /* 报文除CRC校验值之前的数据部分 */
            byte[] b = new byte[len - 2];
            System.arraycopy(bytes, 0, b, 0, len - 2);

            /* 报文内容计算CRC字符 */
            String destCRC = HexConvertUtil.BinaryToHexString(HexConvertUtil.hexStringToBytes(CRCUtil.getCRC(b)));
            if (!srcCRC.equals(destCRC)) {
                throw new RuntimeException("CRC校验错误！");
            }

            /* 数据字节数量 */
            int regNum = (bytes[2] >> 4 & 0x0f) * 16 + (bytes[2] & 0x0f);

            /* 传感器数据 */
            byte[] data = new byte[regNum];
            System.arraycopy(bytes, 3, data, 0, regNum);

            /* regNum-4 舍去最高温2位，舍去报警状态2位// FC19 */
            for (int i = 0; i < regNum - 4; i += 2) {
                int t = Integer.parseInt(String.valueOf((data[i] & 0xff) * 256 + (data[i + 1] & 0xff)));
                log.debug("数据位 {}",t);
                if (t == 64537) {
                    continue;
                }
                t = t <= 32767 ? t : t - 65536;

                ReceiveMessage message = new ReceiveMessage();
                message.setType("data");
                message.setInstanceId("temperature-" + ((i + 2) / 2));
                message.setDatetime(System.currentTimeMillis());
                message.addData("temperature", t / 10.0);
                message.setReportMode(com.zhouwr.common.enums.ReportMode.REPORT);

                out.add(message);
            }
        }
    }
}
